package com.ac.scum.log.web.interceptor;

import com.ac.scum.log.bean.Menu;
import com.ac.scum.log.web.dto.login.LoginDTO;
import com.ac.scum.log.web.filter.TokenFilter;
import com.ac.scum.log.web.interceptor.anno.PermissionCheck;
import com.ac.scum.log.web.utils.spring.SpringUtils;
import com.ac.scum.log.web.utils.user.CurrentUserUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Objects;

@Slf4j
@Component
public class PermissionInterceptor implements HandlerInterceptor {


    public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws Exception {
        AntPathMatcher matcher = new AntPathMatcher();
        for (String path : TokenFilter.NoAuthPath) {
            if (matcher.match(path, request.getServletPath())) {
                return true;
            }
        }

        RedisTemplate<String, Object> redisTemplate = SpringUtils.getBean("redisTemplate");
        if (handler instanceof HandlerMethod handlerMethod) {
            PermissionCheck rc = handlerMethod.getMethodAnnotation(PermissionCheck.class);
            if (rc != null) {
                LoginDTO loginDTO = (LoginDTO) redisTemplate.opsForValue().get(CurrentUserUtil.getCurrentToken());
                try {
                    if (loginDTO != null && loginDTO.getMenus() != null) {
                        if (loginDTO.getMenus().stream().anyMatch(item -> item.getPermission().equalsIgnoreCase(rc.permission()))) {
                            return true;
                        }
                    }
                } catch (Exception e) {
                    log.error("权限校验失败 :{}", e.getMessage());
                }
                log.error("权限校验失败 :用户{} 未拥有权限{}", Objects.requireNonNull(loginDTO).getAdminUser().getPhone(), rc.permission());
                response.setStatus(403);
                return false;
            }
        }
        return true;
    }
}
